package main

import (
	"context"
	"fmt"
	"strconv"
	"time"

	"github.com/chromedp/chromedp"
)

const MajorPrefixURL = "https://yz.chsi.com.cn/sch/listYzZyjs--schId-"
const MajorMiddlefixURL = ",categoryId-"
const MajorSuffixURL = ".dhtml"

func getMajor(schId int64, catId int64) {
	// 创建并共享一个 Chrome 上下文
	ctx, cancel := chromedp.NewContext(context.Background())
	defer cancel()
	// 设置超时时间
	ctx, cancel = context.WithTimeout(ctx, 20*time.Second)
	defer cancel()

	// 执行任务
	var err error
	// 目标网址
	url := MajorPrefixURL + strconv.Itoa(int(schId)) + MajorMiddlefixURL + strconv.Itoa(int(catId)) + MajorSuffixURL // 替换为目标网址
	err = chromedp.Run(ctx, chromedp.Navigate(url))
	if err != nil {
		fmt.Println("爬取失败: \n", err)
	}

	// 暂定遍历200为上限，为空就自动停掉
	var defaultLength = 2
	var i, j int
	// 遍历获取第一层专业类目
	for i = 1; i < 2; i++ {
		err, result := runTask1(ctx, schId, catId, 1, i, 0)
		println("爬取第 " + strconv.Itoa(i) + " 个专业类目信息：" + result)
		if err != nil {
			println("专业类目爬取失败: %v", err)
			continue //如果失败，继续进行下一个专业类目的爬取
		}
		// 遍历获取第二层专业代码信息
		for j = 1; j <= defaultLength; j++ {
			err, result := runTask1(ctx, schId, catId, 2, i, j)
			println("爬取第 " + strconv.Itoa(j) + " 个专业代码信息：" + result)
			if err != nil {
				println("专业代码爬取失败: %v", err)
				continue //如果失败，继续进行下一个专业类目的爬取
			}
		}
	}
}

// 运行爬虫任务
func runTask(ctx context.Context, schId int64, catId int64, taskType int, i int, j int) (error, string) {

	// 定义存储结果的变量
	var result string

	// 目标网址
	url := MajorPrefixURL + strconv.Itoa(int(schId)) + MajorMiddlefixURL + strconv.Itoa(int(catId)) + MajorSuffixURL // 替换为目标网址

	// 执行任务
	var err error
	if taskType == 1 {
		// 院系类目
		err = chromedp.Run(ctx,
			// 打开目标页面
			chromedp.Navigate(url),

			// 等待页面动态加载
			chromedp.Sleep(10*time.Second),

			// 获取院系所有类目和所有专业信息
			chromedp.WaitVisible(`/html/body/div[1]/div[3]/div[2]/div[1]/div[`+strconv.Itoa(i)+`]`, chromedp.BySearch),

			// 获取院系类目
			chromedp.Text(`/html/body/div[1]/div[3]/div[2]/div[1]/div[`+strconv.Itoa(i)+`]`, &result, chromedp.BySearch),
		)
	}
	if taskType == 2 {
		// 院系下专业代码信息
		err = chromedp.Run(ctx,
			// 打开目标页面
			chromedp.Navigate(url),
			// 等待页面动态加载
			chromedp.Sleep(10*time.Second),

			// 等待特定元素加载 (XPath 表达式)
			chromedp.WaitVisible(`/html/body/div[1]/div[3]/div[2]/div[1]/div[`+strconv.Itoa(i)+`]/div[`+strconv.Itoa(j)+`]/ul`, chromedp.BySearch),

			// 获取所有专业信息
			chromedp.Text(`/html/body/div[1]/div[3]/div[2]/div[1]/div[`+strconv.Itoa(i)+`]/div[`+strconv.Itoa(j)+`]/ul`, &result, chromedp.BySearch),
		)
	}

	// 检查是否出错
	if err != nil {
		fmt.Println("爬取失败: \n", result)
	}

	// 输出结果
	fmt.Println("提取到的内容: \n", result)

	return err, result
}

// 运行爬虫任务
func runTask1(ctx context.Context, schId int64, catId int64, taskType int, i int, j int) (error, string) {

	// 定义存储结果的变量
	var result string

	// 执行任务
	var err error

	if taskType == 1 {
		// 院系类目
		err = chromedp.Run(ctx,
			// 等待特定元素加载 (XPath 表达式)
			chromedp.WaitVisible(`/html/body/div[1]/div[3]/div[2]/div[1]/div[`+strconv.Itoa(i), chromedp.BySearch),
			chromedp.Text(`/html/body/div[1]/div[3]/div[2]/div[1]/div[`+strconv.Itoa(i)+`]`, &result, chromedp.BySearch),
		)
	}
	if taskType == 2 {
		// 院系下专业代码信息
		err = chromedp.Run(ctx,
			// 等待特定元素加载 (XPath 表达式)
			chromedp.WaitVisible(`/html/body/div[1]/div[3]/div[2]/div[1]/div[`+strconv.Itoa(i)+`]/div[`+strconv.Itoa(j)+`]/ul`, chromedp.BySearch),
			chromedp.Text(`/html/body/div[1]/div[3]/div[2]/div[1]/div[`+strconv.Itoa(i)+`]/div[`+strconv.Itoa(j)+`]/ul`, &result, chromedp.BySearch),
		)
	}

	// 检查是否出错
	if err != nil {
		fmt.Println("爬取失败: \n", result)
	}

	// 输出结果
	fmt.Println("提取到的内容: \n", result)

	return err, result
}

func main() {
	println("start---------------->")
	getMajor(367878, 692157514)
	println("ending--------------->")
}
